package com.elcom.emocbc.cbm.smsbroadcast;

import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import com.elcom.util.miscellaneous.ByteUtil;
import com.elcom.util.miscellaneous.HexUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class TestSmsAsCB2 {

    private final static Logger logger = LoggerFactory.getLogger(TestSmsAsCB2.class);
    private static final int PART_LENGTH = 140;
    private static final int HEADER = 2; /* 2 byte header la MessageID + Concate */

    private static final int SMSDD_PAGE_LENGTH = PART_LENGTH - HEADER;

//---------------------------------------------------------------------------------------------------------------------
    /**
     * - hexString: + Chua bao gom 2 Header Bytes la MessageID, Concate + Chua
     * bao gom cac Padding Bytes la 0x0d
     */
    public static byte[][] split(byte[] body_data, Integer msgId) {
//        byte[] body_data = HexUtil.convertHexStringToBytes(hexString);
        int body_length = body_data.length;

        int totalPart = body_length / SMSDD_PAGE_LENGTH;
        if (body_length % SMSDD_PAGE_LENGTH > 0) {
            totalPart++;
        }

        logger.debug("[SmsBroadcast] MsgId before encode: {}", msgId);
        byte messageId = getSmsBroadcastId(msgId);
        logger.debug("[SmsBroadcast] MsgId after encode: {}", HexUtil.convertByteToHexString(messageId));

        byte[][] segments = new byte[totalPart][];

        for (int i = 0; i < totalPart; i++) {
            int lr = SMSDD_PAGE_LENGTH;
            if (totalPart - i == 1) { /* manh cuoi cung */

                lr = body_length - i * SMSDD_PAGE_LENGTH;
            }
            byte[] dr = new byte[lr];
            System.arraycopy(body_data, (i * SMSDD_PAGE_LENGTH), dr, 0, lr);

            ChannelBuffer buf = ChannelBuffers.dynamicBuffer();

            /* Header */
            byte[] header = new byte[2];
            header[0] = messageId;
            header[1] = ByteUtil.MAKEBYTE((byte) (i + 1), (byte) totalPart);
            buf.writeBytes(header);

            /* Phan du lieu tho */
            buf.writeBytes(dr);

            /* Fill 0x0d cho du 140 byte */
            while (buf.readableBytes() < PART_LENGTH) {
                buf.writeByte((byte) 0x0d);
            }

            byte[] segment = new byte[buf.readableBytes()];
            buf.getBytes(buf.readerIndex(), segment);
            segments[i] = segment;
        }

        return segments;
    }

//---------------------------------------------------------------------------------------------------------------------
    private static volatile int sms_broadcast_id = 0x01;

    public static synchronized byte getSmsBroadcastId(Integer msgId) {
        if (msgId == null) {
            if (sms_broadcast_id > 0xFF) {
                sms_broadcast_id = 0x01;
            }
            msgId = sms_broadcast_id++;
        }

        return calcChecksum(new byte[]{(byte) msgId.intValue()});
    }

//---------------------------------------------------------------------------------------------------------------------
    private static byte calcChecksum(byte[] val) {
        byte result = 0;
        byte len = (byte) val.length;
        for (int i = 0; i < len; i++) {
            byte current = val[i];
            for (int j = 0; j < 8; j++) {
                if ((current & 0x1) != 0) {
                    current = (byte) (current >> 1 ^ 0x5D);
                } else {
                    current = (byte) (current >> 1);
                }
            }
            result = (byte) (result ^ current);
        }

        result = (byte) (result | 0xFFFFFF80);

        if ((byte) (result & 0xFFFFFFF0) == -128) {
            result = (byte) (result | 0x10);
        }
        return result;
    }

//---------------------------------------------------------------------------------------------------------------------
    public static void main(String[] args) {
        String hexString = "4e3083000381374300a00953565320313030313809486169436f6e476933a00853565320393939380a436f4e616e67486f7433b38106308830303065313633330e43687579656e43756f694b6861630302009e54726f6e67206d6f74206b686163682073616e206f204c6f6e646f6e2e436f207469656e67206368756f6e672072656f206f207175617920746965702074616e2e4e68616e207669656e2070687563207675206e686174206d6179207661206e67686520636f207469656e67206e67756f69206e6f693a20227475207469207475207475207475207475212220416e68206e6179206368616e6720203e3e02009f6869657520646175206461792062656e206b6961206e6f69206769206c69656e20646170206d61792e4c616920636f207469656e67206368756f6e672072656f2c76612076616e20636175206e6f692061793a20227475207469207475207475207475207475222e4e68616e207669656e207068756320767520646170206d61792074686174206d616e682e4d6f74206c617420736175206d6f7420203e3e020082616e68206368616e672064656e207661207175617420226e6179206f6e6720636f2068696575207469656e6720616e68206b686f6e672068613f22546f69206461206e6f692033206c616e20726f6920226d616e67206e6761792032206c79207472612076612070686f6e672032323222202874776f2074656120746f2032323229";

        while (true) {
            byte[][] sms_segments = split(HexUtil.convertHexStringToBytes(hexString), null);
            for (byte[] sms : sms_segments) {
                String dump = HexUtil.convertBytesToHexString(sms);
                System.out.println(dump);
            }

            System.out.println("============");
            try {
                Thread.sleep(15000L);
            } catch (InterruptedException e) {
            }
        }

    }
}
